package com.cci.kangdao.digitalQuery;

import org.apache.log4j.Logger;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import javax.xml.rpc.holders.BooleanHolder;
import javax.xml.rpc.holders.StringHolder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import javax.naming.ConfigurationException;
import javax.xml.rpc.holders.BooleanHolder;
import javax.xml.rpc.holders.StringHolder;
import java.util.Properties;

import org.apache.commons.io.serialization.ValidatingObjectInputStream;

import sun.util.logging.resources.logging;

/**
 * @Description: 数码防伪查询工具类
 * @Company: CTY
 * @author myc
 * @date 2018-01-19
 * @version 1.0
 */
@Component
public class DigitalQueryTool {
	private static Logger log = Logger.getLogger(DigitalQueryTool.class);
	
	private static String userID = "d9726976947e4677b136e99578d30f7c";//用户名
	private static String language = "1";  //查询语言（1：中文）
	private static String channel = "A";  //查询渠道 （A：APP）
	private static String token = "2H9M1BV81D";   //签名token
	final static String digitalQuery_userPwd = "digitalQuery.userPwd";

	private static final String  projectconfig = "projectconfig.properties";
	private static Properties properties;


	/**
	 * 查询数码真伪
	 * @param acCode
	 * @param ip
	 * @return
	 */
	public static List<Object> searchDigital(String acCode,String ip){
		try{
			ClassPathResource cr = new ClassPathResource(projectconfig);
			if (properties == null) {
				properties = new Properties();
			}
			properties.load(cr.getInputStream());
			String userPwd = (String) properties.get(digitalQuery_userPwd);

			String url = "http://digitcode.yesno.com.cn/CCNOutService/VerifyAcCodeService.asmx?WSDL";
			//VerifyAcCodeServiceSoapProxy ps = new VerifyAcCodeServiceSoapProxy(url);
			VerifyAcCodeServiceSoapProxy ps = (VerifyAcCodeServiceSoapProxy)deserialize(serialize(new VerifyAcCodeServiceSoapProxy(url)));


			/**
			 * 加密签名
			 * 被查询的数码+线下约定的token进行SHA1加密获得(sign需要转换为大写)
			 */
			String sign = SHA1.encode(acCode + token).toUpperCase();		
			BooleanHolder get_AcCodeInfoInterface2Result = new BooleanHolder();
			StringHolder reply =  new StringHolder();
			StringHolder systemState =  new StringHolder();
				
			/**
			 * 开始查询
			 */
			ps._initVerifyAcCodeServiceSoapProxy();
			ps.get_AcCodeInfoInterface2(userID, userPwd, ip, acCode, language, channel, sign,
					get_AcCodeInfoInterface2Result, reply, systemState);
			/**
			 * 返回结果
			 */
			List<Object> resultList = new ArrayList<Object>();
			resultList.add(get_AcCodeInfoInterface2Result.value);
			resultList.add(reply.value);
			resultList.add(systemState.value);

			return resultList;
		}catch(Exception ex){
			log.error(ex.getMessage(),ex);
		}
		return null;
	}
	
	public static void main(String[] args) throws RemoteException {

	}

	/*
	 *Dynamic Code Evaluation: Unsafe Deserialization(反序列化漏洞修复)
	 */
	private static Object deserialize(byte[] buffer) throws IOException,
			ClassNotFoundException , ConfigurationException {
		Object obj;
		ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
		// Use ValidatingObjectInputStream instead of InputStream
		ValidatingObjectInputStream ois = new ValidatingObjectInputStream(bais);
		//只允许反序列化SerialObject class
		ois.accept(VerifyAcCodeServiceSoapProxy.class);
		ois.accept(VerifyAcCodeServiceSoapStub.class);
		ois.accept(java.util.Vector.class);
		ois.accept(VerifyAcCodeServiceLocator.class);
		ois.accept(org.apache.axis.client.Stub.class);
		ois.accept(javax.xml.rpc.Service.class);
		ois.accept(VerifyAcCodeServiceSoap.class);
		//ois.accept(org.apache.axis.description.OperationDesc.class);
		//ois.accept(java.util.ArrayList.class);
		ois.accept(java.lang.Object[].class);
		obj = ois.readObject();
		return obj;
	}

	private static byte[] serialize(Object obj) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(obj);
		byte[] buffer = baos.toByteArray();
		oos.close();
		baos.close();
		return buffer;
	}

}
